home *** CD-ROM | disk | FTP | other *** search
- {*********************************************************}
- {* Trie *}
- {* Copyright (c) Julian M Bucknall 1998 *}
- {* All rights reserved. *}
- {*********************************************************}
- {* A simple trie class *}
- {*********************************************************}
-
- {Note: this unit is released as freeware. In other words, you are free
- to use this unit in your own applications, however I retain all
- copyright to the code. JMB}
-
- {$IFDEF VER80}
- !! Error
- This unit uses long strings only. In other words, you must be using
- Delphi 2 or later.
- {$ENDIF}
-
- unit Trie;
-
- interface
-
- type
- PTrieNode = ^TTrieNode;
- TTrieNode = array [#0..#255] of PTrieNode;
-
- type
- TTrie = class
- protected {private}
- FRoot : PTrieNode;
- FNodeCount : integer;
- protected
- procedure KillNodes(aRoot : PTrieNode);
- function FindPrim(const S : string;
- var aData : pointer;
- var aNode : PTrieNode;
- var aChPos : integer) : boolean;
- public
- constructor Create;
- destructor Destroy; override;
-
- procedure AddObject(const S : string; aData : pointer);
- function FindString(const S : string; var aData : pointer) : boolean;
-
- property NodeCount : integer read FNodeCount;
- end;
-
- implementation
-
- {===TTrie============================================================}
- constructor TTrie.Create;
- begin
- {allocate the root node}
- New(FRoot);
- FNodeCount := 1;
- FillChar(FRoot^, sizeof(TTrieNode), 0);
- end;
- {--------}
- destructor TTrie.Destroy;
- begin
- {destroy all nodes recursively}
- KillNodes(FRoot);
- end;
- {--------}
- procedure TTrie.AddObject(const S : string; aData : pointer);
- var
- DummyData : pointer;
- Node : PTrieNode;
- NewNode : PTrieNode;
- ChPos : integer;
- i : integer;
- begin
- {if the string already exists, ignore the call}
- if FindPrim(S, DummyData, Node, ChPos) then
- Exit;
- {now create a node for each remaining character in S}
- for i := ChPos to length(S) do begin
- New(NewNode);
- inc(FNodeCount);
- FillChar(NewNode^, sizeof(TTrieNode), 0);
- Node^[S[i]] := NewNode;
- Node := NewNode;
- end;
- {patch the terminator link to the given data}
- Node^[#0] := aData;
- end;
- {--------}
- function TTrie.FindPrim(const S : string;
- var aData : pointer;
- var aNode : PTrieNode;
- var aChPos : integer) : boolean;
- var
- Node : PTrieNode;
- i : integer;
- begin
- Node := FRoot;
- for i := 1 to succ(length(S)) do begin
- aNode := Node;
- Node := Node^[S[i]];
- if (Node = nil) then begin
- Result := false;
- aData := nil;
- aChPos := i;
- Exit;
- end;
- end;
- Result := true;
- aData := Node;
- end;
- {--------}
- function TTrie.FindString(const S : string; var aData : pointer) : boolean;
- var
- DummyNode : PTrieNode;
- DummyChPos: integer;
- begin
- Result := FindPrim(S, aData, DummyNode, DummyChPos);
- end;
- {--------}
- procedure TTrie.KillNodes(aRoot : PTrieNode);
- var
- Ch : char;
- begin
- if (aRoot <> nil) then begin
- {kill all children, recursively; ignore #0}
- for Ch := #1 to #255 do
- KillNodes(aRoot^[Ch]);
- {kill root node}
- Dispose(aRoot);
- end;
- end;
- {====================================================================}
-
- end.
-